#pragma once

#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>
#include <vector>
#include <functional>

using namespace std;

using func_t = function<void(string)>;

template<class T>
class Thread
{
public:
    Thread(func_t func, string &threadname, T data)
        :_tid(0)
        ,_isrunning(false)
        ,_func(func)
        ,_threadname(threadname)
        ,_data(data)
    {}

    static void *ThreadRoutine(void *args) // 类内方法
    {
        // (void *)args; // 为了让编译器不报警
        Thread *ts = static_cast<Thread *>(args);

        ts->_func(ts->_data);

        return nullptr;
    }

    bool Start()
    {
        int n = pthread_create(&_tid, nullptr, ThreadRoutine, this);
        if(n == 0)
        {
            _isrunning = true;
            return true;
        }
     
        return false;
    }

    bool Join()
    {
        if(!_isrunning) return true;
        int n = pthread_join(_tid, nullptr);
        if(n == 0)
        {
            _isrunning = false;
            return true;
        }
        
        return false;
    }

    string threadname()
    {
        return _threadname;
    }

    bool IsRunning()
    {
        return _isrunning;
    }

    ~Thread()
    {}
private:
    pthread_t _tid;
    string _threadname;
    bool _isrunning;
    func_t _func;
    T _data;
};